#include <bits/stdc++.h>

using namespace std;

template <typename DataType>
vector<vector<DataType>> read_data(const string &filename)
{
    ifstream is(filename);
    vector<vector<DataType>> data;
    while (is)
    {
        DataType num1, num2;
        char delimiter;
        is >> num1 >> delimiter >> num2;
        data.push_back({num1, num2});
    }
    is.close();
    return std::move(data);
}

template <typename DType>
double distance(const vector<DType> &p1, const vector<DType> &p2)
{
    double res = 0;
    for (int i = 0; i < p1.size(); ++i)
    {
        res += pow(p1[i] - p2[i], 2);
    }
    res = sqrt(res);
    return res;
}

struct Wrapper
{
    size_t index;
    double distance;

    Wrapper() {}

    Wrapper(size_t index, double distance) : index(index), distance(distance)
    {
    }

    bool operator<(const Wrapper &idx) const
    {
        return this->distance < idx.distance;
    }
};

int main()
{
    vector<vector<double>> data = read_data<double>("data/t54k.txt");
    const int k = data.size();
    vector<vector<size_t>> neighbors;
    neighbors.reserve(data.size());
    for (size_t index = 0; index < data.size(); ++index)
    {
        priority_queue<Wrapper> q;
        vector<double> source = data[index];
        for (size_t index2 = 0; index2 < data.size(); ++index2)
        {
            Wrapper wrapper(index2, distance(data[index2], source));
            q.push(wrapper);
            if (q.size() > k)
            {
                q.pop();
            }
        }
        vector<size_t> indeces(q.size());
        vector<size_t>::reverse_iterator iter = indeces.rbegin();
        while (q.empty() == false)
        {
            *iter++ = q.top().index;
            q.pop();
        }
        neighbors.emplace_back(std::move(indeces));
        printf("\r%lu/%lu", index, data.size() - 1);
        fflush(stdout);
    }
    return 0;
}